#include "ExpAST.h"
#include "Globe.h"
#include <iostream>
#include "parser.h"
#include "Globe.h"
#pragma warning(disable:4267)
using std::cout;
using std::endl;

unique_ptr<BaseExpAST> parser::parsePostfixExp()
{
    unique_ptr<PostfixAST>ret;
    unique_ptr<BaseExpAST>content = this->parseVal();
    switch (this->lexer->next_token())
    {
    case TOK::INCR:
        this->lexer->match(TOK::INCR);
        ret.reset(new PostfixAST);
        ret->op = PostfixAST::INCR;
        ret->content = std::move(content);
        return ret;
    case TOK::DECR:
        this->lexer->match(TOK::DECR);
        ret.reset(new PostfixAST);
        ret->op = PostfixAST::DECR;
        ret->content = std::move(content);
        return ret;
    default:break;
    }
    return content;
}

void PostfixAST::Dump() const
{
    cout << "{\"type\":\"Postfix\",\"op\":\"";
    switch (this->op)
    {
    case INCR:
        cout << "++";
        break;
    case DECR:
        cout << "--";
        break;
    default:break;
    }
    cout << "\",\"lVal\":";
    this->content->Dump();
    cout << "}";
}

bool PostfixAST::is_lval() const
{
    if (this->op == DEFAULT)
        return this->content->is_lval();
    return false;
}

void PostfixAST::Analyze() const
{
    this->content->Analyze();
    if (this->op == DEFAULT)return;
    GENASM(cmd_code::MOV, CVR(EAX), CVR(EDX));
    if (this->op == INCR) {
        GENASM(cmd_code::ADD, CVR(EAX), CVI(1));
    }
    else
        GENASM(cmd_code::SUB, CVR(EAX), CVI(1));
    GENASM(cmd_code::MOV, CVR(EAX), this->content->get_address());
    GENASM(cmd_code::MOV, CVR(EDX), CVR(EAX));
}
